package org.spring.aop;

import java.lang.reflect.Method;

/**
 * 检查目标方法是否有资格获得通知
 *
 * @author 李坤
 * @date 2022/4/17 22:27
 */
public interface MethodMatcher {

    /**
     * 这个 MethodMatcher 是否是动态的，也就是说，即使 2-arg 匹配方法返回 {@code true}，
     * 也必须在运行时对 {@link #matches(Method, Class, Object[])} 方法进行最终调用？
     * <p>
     * 可以在创建 AOP 代理时调用，无需在每次方法调用之前再次调用，
     *
     * @return 如果静态匹配通过，则是否需要通过 3-arg {@link #matches(Method, Class, Object[])} 方法进行运行时匹配
     */
    boolean isRuntime();

    /**
     * 执行静态检查给定方法是否匹配。
     * <p>
     * 如果这返回 {@code false} 或 {@link #isRuntime()} 方法返回 {@code false}，
     * 则没有运行时检查（即没有 {@link #matches(Method, Class, Object[])} 调用) 将进行。
     *
     * @param method      候选方法
     * @param targetClass 目标类
     *
     * @return 此方法是否静态匹配
     */
    boolean matches(Method method, Class<?> targetClass);

    /**
     * 检查此方法是否存在运行时（动态）匹配，该匹配必须是静态匹配的。
     * <p>
     * 仅当 2-arg 匹配方法为给定方法和目标类返回 {@code true} 并且 {@link #isRuntime()} 方法返回 {@code true} 时，才会调用此方法。
     * 在建议链中较早的任何建议运行之后，在建议可能运行之前立即调用。
     *
     * @param method      候选方法
     * @param targetClass 目标类
     * @param args        方法的参数
     *
     * @return 是否存在运行时匹配
     *
     * @see MethodMatcher#matches(Method, Class)
     */
    boolean matches(Method method, Class<?> targetClass, Object... args);

}
